package com.publicprintingwithjason;

// Environment code for project publicprintingwithjason

import jason.asSyntax.Literal;
import jason.asSyntax.Structure;
import jason.environment.Environment;

import java.awt.Dimension;

import com.golden.gamedev.GameLoader;
import com.publicprintingwithjason.gui.GuiControl;
import com.publicprintingwithjason.gui.User;

public class PublicPrintingEnvironment extends Environment {

	private GuiControl guiController;

	/** Called before the MAS execution with the args informed in .mas2j */
	@Override
	public void init(String[] args) {
		super.init(args);

		// start the gui
		guiController = new GuiControl();

		Thread t = new Thread(new Runnable() {
			public void run() {
				GameLoader game = new GameLoader();
				game.setup(guiController, new Dimension(825, 600), false);
				game.start();
			}
		});
		t.start();

		// wait for the gui to be ready
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public boolean executeAction(String agName, Structure action) {
		clearPercepts(agName);

		// customer actions
		if (agName.contains("customer")) {

			// gets the index of the customer
			int num = Integer.parseInt(agName.substring(agName.length() - 1)) - 1;

			// gets a pointer to the user on the gui
			User customer = guiController.getUsers()[num];

			// if this is a walkto action
			if (action.getFunctor().equals("walkto")) {

				// get the destination that the customer wants to go to
				String destination = action.getTerm(0).toString();

				// if its anywhere
				if (destination.equals("anywhere")) {
					// we will make it walk randomly
					if (!customer.hasDestination()) {
						System.out.println("[" + agName + "] walking around...");
						guiController.randomWalk(num);
					}
				} else {
					// if its not anywhere, it should be a printer
					// get the index of the printer
					int dest = Integer.parseInt(destination.substring(destination.length() - 1)) - 1;

					// make it walk to the printer
					if (!customer.hasDestination()) {
						System.out.println("[" + agName + "] walking to " + destination);
						guiController.moveToPrinter(num, dest);
					}

					// if it has arrived there, add the percept at(printerX) so
					// the customer will know that he has arrived and is able to
					// get the print
					if (customer.getPosition().getX() == guiController.getPrinterEntrancePosition(dest).getX()
							&& customer.getPosition().getY() == guiController.getPrinterEntrancePosition(dest).getY()) {
						System.out.println("[" + agName + "] arrived " + destination);
						addPercept(agName, Literal.parseLiteral("at(" + destination + ")"));
					}
				}

			}
			// if it is a getprint action, just write on the screen that he`s
			// gotten the print
			else if (action.getFunctor().equals("getprint")) {
				System.out.println("[" + agName + "] getting job...");

			}
		}
		// server actions
		else if (agName.contains("server")) {

		}
		// printer actions
		else if (agName.contains("printer")) {
			// gets the index of the printer
			int num = Integer.parseInt(agName.substring(agName.length() - 1)) - 1;

			// print action
			if (action.getFunctor().equals("print")) {
				// gets the index of the customer who asked the print
				String c = action.getTerm(0).toString();

				System.out.println("[" + agName + "] printing for " + c);

				// while printing change the color to yellow
				guiController.chancePrinterColor(num, 1);

				// simulates the printing process
				try {
					Thread.sleep(2000);
				} catch (Exception e) {
				}

				// as soon as the printing is done, change the color back to
				// green
				guiController.chancePrinterColor(num, 0);

			}
			// updatestatus action
			else if (action.getFunctor().equals("updatestatus")) {
				// gets the status
				String s = action.getTerm(0).toString();

				// changes the color acoording to the status
				if (s.equals("outoforder"))
					guiController.chancePrinterColor(num, 2);
				else if (s.equals("busy"))
					guiController.chancePrinterColor(num, 1);
				else if (s.equals("ok"))
					guiController.chancePrinterColor(num, 0);
			}
		}
		// supplier actions
		else if (agName.contains("supplier")) {

			// gets the pointer to the supplier at the gui
			User supplier = guiController.getSupplier();

			// if its a walkto action
			if (action.getFunctor().equals("walkto")) {
				// gets the destination
				String destination = action.getTerm(0).toString();
				// which should be a printer, so we will get the index of the
				// printer
				int dest = Integer.parseInt(destination.substring(destination.length() - 1)) - 1;

				// if the supplier is already there, add the percept
				// at(printerX)
				if (supplier.getPosition().getX() == guiController.getPrinterEntrancePosition(dest).getX()
						&& supplier.getPosition().getY() == guiController.getPrinterEntrancePosition(dest).getY()) {
					System.out.println("[" + agName + "] arrived " + destination);
					addPercept(agName, Literal.parseLiteral("at(" + destination + ")"));
				}
				// otherwise tell him to keep going there
				else if (!supplier.hasDestination()) {
					System.out.println("[" + agName + "] going to " + destination);
					guiController.sendSuplyManToPrinter(dest);
				}
			}
			// gohome action
			else if (action.getFunctor().equals("gohome")) {

				// if the supplier is already there, add the percept at(home)
				if (supplier.getPosition().getX() == guiController.getSupplierHomePosition().getX()
						&& supplier.getPosition().getY() == guiController.getSupplierHomePosition().getY()) {
					System.out.println("[" + agName + "] arrived home");
					addPercept(agName, Literal.parseLiteral("at(home)"));
				}
				// otherwise tell him to keep going there
				else if (!supplier.hasDestination()) {
					System.out.println("[" + agName + "] going home");
					guiController.sendSuplyManHome();
				}
			}
		}

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
		}

		return true;
	}

	/** Called before the end of MAS execution */
	@Override
	public void stop() {
		super.stop();

		guiController.stop();
	}
}
